package com.ruoyi.common.core.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.system.SystemUtil;
import com.ruoyi.common.core.domain.R;

import java.net.URLEncoder;
import java.util.*;

public class WeChatUtil {

    private static Log log = Log.get();

    private static final String APIKEY = "1ec4a8c4a8eb4da9bb380585d4bb1308";

    private static final String MCH_ID = "1619627895";

    /**
     *
     * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序），并且生成参数串<br>
     * 实现步骤: <br>
     *
     * @param paraMap   要排序的Map对象
     * @param urlEncode   是否需要URLENCODE
     * @param keyToLower    是否需要将Key转换为全小写
     *            true:key转化成小写，false:不转化
     * @return
     */
    public static String formatUrlMap(Map<String, Object> paraMap, boolean urlEncode, boolean keyToLower)
    {
        String buff = "";
        Map<String, Object> tmpMap = paraMap;
        try
        {
            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(tmpMap.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>()
            {

                @Override
                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2)
                {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造返回字符串键值对的格式
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<String, Object> item : infoIds)
            {
                if (StrUtil.isNotBlank(item.getKey()))
                {
                    String key = item.getKey();
                    String val = item.getValue().toString();
                    if (urlEncode)
                    {
                        val = URLEncoder.encode(val, "utf-8");
                    }
                    if (keyToLower)
                    {
                        buf.append(key.toLowerCase() + "=" + val);
                    } else
                    {
                        buf.append(key + "=" + val);
                    }
                    buf.append("&");
                }

            }
            buff = buf.toString();
            if (buff.isEmpty() == false)
            {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e)
        {
            return null;
        }
        return buff;
    }

    public static String getSign(Map<String, Object> paraMap){
        String stringA = formatUrlMap(paraMap,false,false);
        String stringSignTemp = stringA + "&key="+APIKEY;
        String sign = SecureUtil.md5(stringSignTemp).toUpperCase();
        return sign;
    }

    /**
     * 培训支付订单预支付
     * @param appid
     * @param body
     * @param outTradeNo
     * @param totalFee
     * @param openid
     * @return
     */
    public static Map<String,Object> payUnifiedorderMA(String appid,String body,String outTradeNo,Long totalFee,String openid){
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        Map param = new HashMap();
        param.put("appid",appid);
        param.put("mch_id",MCH_ID);
        param.put("nonce_str", IdUtil.simpleUUID());
        param.put("body",body);
        param.put("out_trade_no", outTradeNo);
        param.put("trade_type","JSAPI");
        param.put("total_fee",totalFee);
        param.put("openid",openid);
        param.put("spbill_create_ip", SystemUtil.getHostInfo().getAddress());
        param.put("notify_url","https://www.tddst.com/api/ruoyi-miniapp/MaintainerApply/open/wxPayNotify");//http://120.77.242.141:9333/fraSeatAgreement/open/wxPayNotify");
        param.put("sign",getSign(param));


        String xmlStr = XmlUtil.mapToXmlStr(param);

        log.debug(xmlStr);
        String resStr = HttpRequest.post(url).header(Header.CONTENT_TYPE,"application/xml").body(xmlStr).execute().body();
        System.out.println(resStr);
        Map res = XmlUtil.xmlToMap(resStr);
        if("SUCCESS".equals(res.get("return_code"))){
            if("SUCCESS".equals(res.get("result_code"))){
                return res;
            }else {
                //生成预支付订单失败
                log.error("生成预支付订单失败==>>业务失败==>>"+res.get("err_code")+"==>>"+res.get("err_code_des"));
                return null;
            }
        }else {
            //生成预支付订单失败
            log.error("生成预支付订单失败==>>"+res.get("return_msg"));
            return null;
        }
    }

    public static Map<String,Object> payUnifiedorder(String appid,String body,String outTradeNo,Long totalFee,String openid){
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        Map param = new HashMap();
        param.put("appid",appid);
        param.put("mch_id",MCH_ID);
        param.put("nonce_str", IdUtil.simpleUUID());
        param.put("body",body);
        param.put("out_trade_no", outTradeNo);
        param.put("trade_type","JSAPI");
        param.put("total_fee",totalFee);
        param.put("openid",openid);
        param.put("spbill_create_ip", SystemUtil.getHostInfo().getAddress());
        param.put("notify_url","https://www.tddst.com/api/ruoyi-miniapp/fraSeatAgreement/open/wxPayNotify");//http://120.77.242.141:9333/fraSeatAgreement/open/wxPayNotify");
        param.put("sign",getSign(param));

        String xmlStr = XmlUtil.mapToXmlStr(param);
        String resStr = HttpRequest.post(url).header(Header.CONTENT_TYPE,"application/xml").body(xmlStr).execute().body();
        System.out.println(resStr);
        Map res = XmlUtil.xmlToMap(resStr);
        if("SUCCESS".equals(res.get("return_code"))){
            if("SUCCESS".equals(res.get("result_code"))){
                return res;
            }else {
                //生成预支付订单失败
                log.error("生成预支付订单失败==>>业务失败==>>"+res.get("err_code")+"==>>"+res.get("err_code_des"));
                return null;
            }
        }else {
            //生成预支付订单失败
            log.error("生成预支付订单失败==>>"+res.get("return_msg"));
            return null;
        }
    }

    public static String createQrCode(String token,String scene){
        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+token;
        Map param = new HashMap();
        param.put("scene",scene);
        param.put("page","pages/out/outCompany/outCompany");
        HttpResponse res = HttpRequest.post(url).body(JSONUtil.toJsonStr(param)).execute();
        String str = Base64.encode(res.bodyStream());
        System.out.println(str);
        return "data:image/png;base64,"+str;
    }

    public static void main(String[] args) {
        System.out.println(SystemUtil.getHostInfo().getAddress());
    }

}
